/**
 * 网络请求工具类
 */
const auth = require('./auth.js')

// API基础URL
// const BASE_URL = 'https://api.housecare.com'
const BASE_URL = 'http://localhost:8102'

// 不需要登录也可以访问的API路径列表
const PUBLIC_APIS = [
  '/api/user/login',
  '/api/user/login/email',
  '/api/user/register',
  '/api/category/list/page/vo',
  '/api/services/list/page/vo',
  '/api/services/get/vo'
]

/**
 * 处理请求错误
 * @param {Object} err - 错误对象
 * @returns {Promise} Promise对象
 */
const handleError = (err) => {
  // 网络请求错误处理
  let message = '请求失败，请检查网络连接'

  if (err && err.errMsg) {
    message = err.errMsg
  } else if (typeof err === 'string') {
    message = err
  }

  // 返回一个rejected的Promise
  return Promise.reject({ message })
}

/**
 * 判断是否为公开API（不需要登录也可访问）
 * @param {string} url - 请求URL
 * @returns {boolean} 是否为公开API
 */
const isPublicApi = (url) => {
  return PUBLIC_APIS.some(api => url.includes(api))
}

/**
 * 请求拦截器
 * @param {Object} options - 请求选项
 * @returns {Object} 处理后的请求选项
 */
const requestInterceptor = (options) => {
  const url = options.url || ''

  // 如果不是公开API，且用户未登录，且不是登录相关接口
  if (!isPublicApi(url) && !auth.isLoggedIn()) {
  }

  // 添加token到请求头
  const token = auth.getToken()
  if (token) {
    options.header = {
      ...options.header,
      'Authorization': token
    }
  }

  // 添加内容类型
  if (!options.header || !options.header['content-type']) {
    options.header = {
      ...options.header,
      'content-type': 'application/json'
    }
  }

  return options
}

/**
 * 响应拦截器
 * @param {Object} response - 响应对象
 * @returns {Promise} Promise对象
 */
const responseInterceptor = (response) => {
  // 请求成功，但业务状态码表示失败
  if (response.statusCode === 200) {
    const { code, message } = response.data

    // token失效处理
    if (code === 401 || code === 403) {
      // 清除登录信息
      auth.clearLoginInfo()

      // 显示提示
      wx.showToast({
        title: '登录已过期，请重新登录',
        icon: 'none'
      })

      // 跳转到登录页
      setTimeout(() => {
        wx.navigateTo({
          url: '/pages/login/login'
        })
      }, 1500)

      return Promise.reject({ message: message || '登录已过期' })
    }

    // 返回完整的响应数据
    return response.data
  }

  // HTTP状态码不为200
  return Promise.reject({
    code: response.statusCode,
    message: '服务器请求错误'
  })
}

/**
 * 发送请求的通用方法
 * @param {string} url - 请求地址
 * @param {Object} options - 请求选项
 * @returns {Promise} Promise对象
 */
const request = (url, options = {}) => {
  // 请求拦截
  options = requestInterceptor(options)

  // 完整URL
  const fullUrl = url.startsWith('http') ? url : BASE_URL + url

  return new Promise((resolve, reject) => {
    wx.request({
      url: fullUrl,
      ...options,
      success: (res) => {
        try {
          const result = responseInterceptor(res)
          resolve(result)
        } catch (err) {
          reject(err)
        }
      },
      fail: (err) => {
        reject(handleError(err))
      }
    })
  })
}

/**
 * 发送GET请求
 * @param {string} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} options - 请求选项
 * @returns {Promise} Promise对象
 */
const get = (url, data = {}, options = {}) => {
  return request(url, {
    method: 'GET',
    data,
    ...options
  })
}

/**
 * 发送POST请求
 * @param {string} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} options - 请求选项
 * @returns {Promise} Promise对象
 */
const post = (url, data = {}, options = {}) => {
  return request(url, {
    method: 'POST',
    data,
    ...options
  })
}

/**
 * 发送PUT请求
 * @param {string} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} options - 请求选项
 * @returns {Promise} Promise对象
 */
const put = (url, data = {}, options = {}) => {
  return request(url, {
    method: 'PUT',
    data,
    ...options
  })
}

/**
 * 发送DELETE请求
 * @param {string} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} options - 请求选项
 * @returns {Promise} Promise对象
 */
const del = (url, data = {}, options = {}) => {
  return request(url, {
    method: 'DELETE',
    data,
    ...options
  })
}

/**
 * 上传文件
 * @param {string} url - 请求地址
 * @param {string} filePath - 文件路径
 * @param {string} name - 文件对应的key
 * @param {Object} formData - 额外的表单数据
 * @param {Object} options - 请求选项
 * @returns {Promise} Promise对象
 */
const uploadFile = (url, filePath, name = 'file', formData = {}, options = {}) => {
  // 请求拦截
  options = requestInterceptor(options)

  // 完整URL
  const fullUrl = url.startsWith('http') ? url : BASE_URL + url

  return new Promise((resolve, reject) => {
    const uploadTask = wx.uploadFile({
      url: fullUrl,
      filePath,
      name,
      formData,
      header: options.header,
      success: (res) => {
        try {
          // 上传接口返回的是字符串，需要转成对象
          if (typeof res.data === 'string') {
            res.data = JSON.parse(res.data)
          }

          const result = responseInterceptor(res)
          resolve(result)
        } catch (err) {
          reject(handleError(err))
        }
      },
      fail: (err) => {
        reject(handleError(err))
      }
    })

    // 如果需要监控上传进度
    if (options.onProgress) {
      uploadTask.onProgressUpdate(options.onProgress)
    }
  })
}

module.exports = {
  request,
  get,
  post,
  put,
  del,
  uploadFile
} 